-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--          http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local Databases = require 'database'
local Col = require 'database.column'

local EfficiencyCurve = require 'power_mgmt.json_types.EfficiencyCurve'

---@class PowerSuppliesTable: Table
---@field UpgradeStatus FieldBase
---@field Id FieldBase
---@field RetransferDelaySeconds FieldBase

---@class CircuitTable: Table
---@field Id FieldBase
---@field CircuitType FieldBase
---@field PhaseWiringType FieldBase
---@field NominalVoltage FieldBase
---@field InputVoltageStatus FieldBase

---@class OnePowerTable: Table
---@field SlotNumber FieldBase
---@field Manufacturer FieldBase
---@field Model FieldBase
---@field PowerSupplyType FieldBase
---@field Presence FieldBase
---@field PowerSupplyChannel FieldBase
---@field SerialNumber FieldBase
---@field PartNumber FieldBase
---@field FirmwareVersion FieldBase
---@field Protocol FieldBase
---@field DeviceLocator FieldBase
---@field ProductionDate FieldBase
---@field Position FieldBase
---@field DMTFPowerSupplyType FieldBase
---@field SourceType FieldBase
---@field IsPartOfSysPower FieldBase
---@field TotalRunningHours FieldBase
---@field LineInputVoltageType FieldBase
---@field RelaySwitchedCount FieldBase
---@field WorkMode FieldBase
---@field DeepSleepStandbyPowerWatts FieldBase
---@field RedundancyGroupId FieldBase
---@field InputVoltageType FieldBase
---@field OutputPowerWatts FieldBase
---@field InputPowerWatts FieldBase
---@field InputVoltage FieldBase
---@field OutputVoltage FieldBase
---@field InputCurrentAmps FieldBase
---@field OutputCurrentAmps FieldBase
---@field Rate FieldBase
---@field RatedCurrentAmps FieldBase
---@field InputFrequencyHz FieldBase
---@field OutputPowerLimitWatts FieldBase
---@field EnvTemperatureCelsius FieldBase
---@field PrimaryChipTemperatureCelsius FieldBase
---@field SecondaryChipTemperatureCelsius FieldBase
---@field InletTemperatureCelsius FieldBase
---@field InnerTemperatureCelsius FieldBase
---@field OutputState FieldBase
---@field CommunicationStatus FieldBase
---@field Failure FieldBase
---@field Fan1Fault FieldBase
---@field Fan2Fault FieldBase
---@field FanFault FieldBase
---@field InputVoltageFault FieldBase
---@field LossOfInput FieldBase
---@field OutputCurrentFault FieldBase
---@field OutputVoltageFault FieldBase
---@field OverTemperature FieldBase
---@field SleepMode FieldBase
---@field DeepSleepEnabled FieldBase
---@field InputVoltageStatus FieldBase
---@field ScanStatus FieldBase
---@field EquipmentMode FieldBase
---@field TPSUStatusHigh FieldBase
---@field TPSUStatusLow FieldBase
---@field MainCircuitVINStatus FieldBase
---@field BackupCircuitVINStatus FieldBase
---@field Health FieldBase
---@field IsUpgrading FieldBase
---@field NormalAndRedundancySupported FieldBase
---@field DualInputVoltageStatus FieldBase
---@field MfrSpecificStatus FieldBase
---@field CMLStatus FieldBase
---@field OtherStatus FieldBase
---@field EfficiencyCurve FieldBase
---@field PowerLevel FieldBase
---@field HardwareVersion FieldBase
---@field PowerState FieldBase
---@field VOUTDebounceMilliseconds FieldBase
---@field DepthOfDischargeVolts FieldBase
---@field CapacityMicrofarads FieldBase
---@field PhysicalInterface FieldBase
---@field RefFrudata FieldBase
---@field UnsupportedProperties FieldBase
---@field AlarmStatus FieldBase
---@field PreAlarmStatus FieldBase
---@field RefSMCChip FieldBase
---@field UpgradeSupported FieldBase
---@field InputState FieldBase

---@class PsuSlotTable: Table
---@field SlotNumber FieldBase
---@field SlotI2cAddr FieldBase
---@field FruI2cAddr FieldBase
---@field Presence FieldBase
---@field I2cChip FieldBase
---@field PsuChip FieldBase
---@field PsuBackupChip FieldBase
---@field FruChip FieldBase
---@field OutputState FieldBase
---@field FruSource FieldBase
---@field IsSupportPowerOnUpgrade FieldBase

---@class AclostRecordTableTable: Table
---@field Id FieldBase
---@field CurTime FieldBase
---@field Flag FieldBase
---@field ResetFlag FieldBase
---@field ShieldAclostEventRecord FieldBase

---@class PowerConfigurationTable: Table
---@field SinglePsuSupport FieldBase
---@field Id FieldBase
---@field MinAvailablePSUCountForUpgrade FieldBase

---@class PowerOutputEfficiencyCurveTable: Table
---@field Position FieldBase
---@field PartNumber FieldBase
---@field InputVoltage FieldBase
---@field LoadPercentRange FieldBase
---@field EfficiencyCurve FieldBase
---@field PowerLevel FieldBase

---@class Power_mgmtDBDatabase
---@field db DataBase
---@field select fun(db:DataBase, table: any, ...): SelectStatement
---@field update fun(db:DataBase, table: any, ...): UpdateStatement
---@field insert fun(db:DataBase, table: any, ...): InsertStatement
---@field PowerSupplies PowerSuppliesTable
---@field Circuit CircuitTable
---@field OnePower OnePowerTable
---@field PsuSlot PsuSlotTable
---@field AclostRecordTable AclostRecordTableTable
---@field PowerConfiguration PowerConfigurationTable
---@field PowerOutputEfficiencyCurve PowerOutputEfficiencyCurveTable
local Power_mgmtDBDatabase = {}
Power_mgmtDBDatabase.__index = Power_mgmtDBDatabase

function Power_mgmtDBDatabase.new(path, datas)
    local db = Databases(path)
    local obj = {db = db}

    obj.PowerSupplies = db:Table('t_power_supplies', {
        UpgradeStatus = Col.IntegerField():cid(1):null():max_length(8):default(0),
        Id = Col.IntegerField():cid(2):primary_key():persistence_key('protect_power_off'):max_length(8),
        RetransferDelaySeconds = Col.IntegerField():cid(3):persistence_key('protect_power_off'):null():max_length(32)
            :default(1800)
    }):create_if_not_exist(datas and datas['t_power_supplies'])
    obj.Circuit = db:Table('t_circuit', {
        Id = Col.IntegerField():cid(1):primary_key():max_length(8),
        CircuitType = Col.TextField():cid(2):null(),
        PhaseWiringType = Col.TextField():cid(3):null(),
        NominalVoltage = Col.TextField():cid(4):null(),
        InputVoltageStatus = Col.IntegerField():cid(5):null():max_length(8)
    }):create_if_not_exist(datas and datas['t_circuit'])
    obj.OnePower = db:Table('t_onepower', {
        SlotNumber = Col.IntegerField():cid(1):primary_key():max_length(32):default(0),
        Manufacturer = Col.TextField():cid(2):null(),
        Model = Col.TextField():cid(3):null(),
        PowerSupplyType = Col.IntegerField():cid(4):null():max_length(32):default(0),
        Presence = Col.IntegerField():cid(5):null():max_length(8):default(0),
        PowerSupplyChannel = Col.IntegerField():cid(6):null():max_length(8):default(0),
        SerialNumber = Col.TextField():cid(7):null(),
        PartNumber = Col.TextField():cid(8):null(),
        FirmwareVersion = Col.TextField():cid(9):null(),
        Protocol = Col.TextField():cid(10):null(),
        DeviceLocator = Col.TextField():cid(11):null(),
        ProductionDate = Col.TextField():cid(12):null(),
        Position = Col.TextField():cid(13):null(),
        DMTFPowerSupplyType = Col.IntegerField():cid(14):null():max_length(8):default(4),
        SourceType = Col.IntegerField():cid(15):null():max_length(8):default(1),
        IsPartOfSysPower = Col.BooleandField():cid(16):null():default(true),
        TotalRunningHours = Col.IntegerField():cid(17):null():max_length(32),
        LineInputVoltageType = Col.TextField():cid(18):null():default('\'Unknown\''),
        RelaySwitchedCount = Col.IntegerField():cid(19):null():max_length(16),
        WorkMode = Col.TextField():cid(20):null(),
        DeepSleepStandbyPowerWatts = Col.IntegerField():cid(21):null():max_length(16):default(65535),
        RedundancyGroupId = Col.IntegerField():cid(22):null():max_length(8),
        InputVoltageType = Col.IntegerField():cid(23):null():max_length(8),
        OutputPowerWatts = Col.RealField():cid(24):null(),
        InputPowerWatts = Col.RealField():cid(25):null(),
        InputVoltage = Col.RealField():cid(26):null(),
        OutputVoltage = Col.RealField():cid(27):null(),
        InputCurrentAmps = Col.RealField():cid(28):null(),
        OutputCurrentAmps = Col.RealField():cid(29):null(),
        Rate = Col.IntegerField():cid(30):null():max_length(16),
        RatedCurrentAmps = Col.IntegerField():cid(31):null():max_length(16),
        InputFrequencyHz = Col.RealField():cid(32):null(),
        OutputPowerLimitWatts = Col.IntegerField():cid(33):null():max_length(32),
        EnvTemperatureCelsius = Col.RealField():cid(34):null(),
        PrimaryChipTemperatureCelsius = Col.RealField():cid(35):null(),
        SecondaryChipTemperatureCelsius = Col.RealField():cid(36):null(),
        InletTemperatureCelsius = Col.RealField():cid(37):null(),
        InnerTemperatureCelsius = Col.RealField():cid(38):null(),
        OutputState = Col.IntegerField():cid(39):null():max_length(8),
        CommunicationStatus = Col.IntegerField():cid(40):null():max_length(8),
        Failure = Col.IntegerField():cid(41):null():max_length(8),
        Fan1Fault = Col.IntegerField():cid(42):null():max_length(8),
        Fan2Fault = Col.IntegerField():cid(43):null():max_length(8),
        FanFault = Col.IntegerField():cid(44):null():max_length(8),
        InputVoltageFault = Col.IntegerField():cid(45):null():max_length(16):default(32768),
        LossOfInput = Col.IntegerField():cid(46):null():max_length(8),
        OutputCurrentFault = Col.IntegerField():cid(47):null():max_length(8),
        OutputVoltageFault = Col.IntegerField():cid(48):null():max_length(8),
        OverTemperature = Col.IntegerField():cid(49):null():max_length(8),
        SleepMode = Col.TextField():cid(50):null(),
        DeepSleepEnabled = Col.IntegerField():cid(51):null():max_length(8),
        InputVoltageStatus = Col.IntegerField():cid(52):null():max_length(8),
        ScanStatus = Col.IntegerField():cid(53):null():max_length(8),
        EquipmentMode = Col.IntegerField():cid(54):null():max_length(8):default(255),
        TPSUStatusHigh = Col.IntegerField():cid(55):null():max_length(32),
        TPSUStatusLow = Col.IntegerField():cid(56):null():max_length(32),
        MainCircuitVINStatus = Col.IntegerField():cid(57):null():max_length(8):default(255),
        BackupCircuitVINStatus = Col.IntegerField():cid(58):null():max_length(8):default(255),
        Health = Col.IntegerField():cid(59):null():max_length(8):default(255),
        IsUpgrading = Col.BooleandField():cid(60):null(),
        NormalAndRedundancySupported = Col.BooleandField():cid(61):null(),
        DualInputVoltageStatus = Col.IntegerField():cid(62):null():max_length(16),
        MfrSpecificStatus = Col.IntegerField():cid(63):null():max_length(8):default(255),
        CMLStatus = Col.IntegerField():cid(64):null():max_length(8),
        OtherStatus = Col.IntegerField():cid(65):null():max_length(8),
        EfficiencyCurve = Col.JsonField():cid(66):null(),
        PowerLevel = Col.TextField():cid(67):null():default('\'N/A\''),
        HardwareVersion = Col.TextField():cid(68):null(),
        PowerState = Col.TextField():cid(69):null():default('\'N/A\''),
        VOUTDebounceMilliseconds = Col.IntegerField():cid(70):null():max_length(32),
        DepthOfDischargeVolts = Col.IntegerField():cid(71):null():max_length(32),
        CapacityMicrofarads = Col.IntegerField():cid(72):null():max_length(32),
        PhysicalInterface = Col.TextField():cid(73):null(),
        RefFrudata = Col.JsonField():cid(74):null(),
        UnsupportedProperties = Col.JsonField():cid(75):null(),
        AlarmStatus = Col.IntegerField():cid(76):null():max_length(32),
        PreAlarmStatus = Col.IntegerField():cid(77):null():max_length(32),
        RefSMCChip = Col.JsonField():cid(78):null(),
        UpgradeSupported = Col.BooleandField():cid(79):null():default(true),
        InputState = Col.IntegerField():cid(80):null():max_length(8)
    }):create_if_not_exist(datas and datas['t_onepower'])
    obj.PsuSlot = db:Table('t_psu_slot', {
        SlotNumber = Col.IntegerField():cid(1):primary_key():max_length(8),
        SlotI2cAddr = Col.IntegerField():cid(2):null():max_length(8),
        FruI2cAddr = Col.IntegerField():cid(3):null():max_length(8),
        Presence = Col.IntegerField():cid(4):null():max_length(8):default(255),
        I2cChip = Col.JsonField():cid(5):null(),
        PsuChip = Col.JsonField():cid(6):null(),
        PsuBackupChip = Col.JsonField():cid(7):null(),
        FruChip = Col.JsonField():cid(8):null(),
        OutputState = Col.IntegerField():cid(9):null():max_length(8),
        FruSource = Col.IntegerField():cid(10):null():max_length(8),
        IsSupportPowerOnUpgrade = Col.BooleandField():cid(11):null():default(true)
    }):create_if_not_exist(datas and datas['t_psu_slot'])
    obj.AclostRecordTable = db:Table('t_aclost_record', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        CurTime = Col.IntegerField():cid(2):persistence_key('protect_power_off'):null():max_length(32),
        Flag = Col.IntegerField():cid(3):persistence_key('protect_power_off'):null():max_length(32),
        ResetFlag = Col.IntegerField():cid(4):persistence_key('protect_reset'):null():max_length(8):default(0),
        ShieldAclostEventRecord = Col.IntegerField():cid(5):persistence_key('protect_power_off'):null():max_length(8)
            :default(255)
    }):create_if_not_exist(datas and datas['t_aclost_record'])
    obj.PowerConfiguration = db:Table('t_power_configuration', {
        SinglePsuSupport = Col.IntegerField():cid(1):null():max_length(8):default(0),
        Id = Col.IntegerField():cid(2):primary_key():max_length(8):default(1),
        MinAvailablePSUCountForUpgrade = Col.IntegerField():cid(3):null():max_length(8):default(255)
    }):create_if_not_exist(datas and datas['t_power_configuration'])
    obj.PowerOutputEfficiencyCurve = db:Table('t_power_efficiency_curve', {
        Position = Col.TextField():cid(1):primary_key(),
        PartNumber = Col.TextField():cid(2):primary_key(),
        InputVoltage = Col.IntegerField():cid(3):primary_key():max_length(16),
        LoadPercentRange = Col.JsonField():cid(4):null(),
        EfficiencyCurve = Col.JsonField():cid(5):null(),
        PowerLevel = Col.TextField():cid(6):null():default('\'N/A\'')
    }):create_if_not_exist(datas and datas['t_power_efficiency_curve'])

    obj.tables = db.tables
    return setmetatable(obj, Power_mgmtDBDatabase)
end

function Power_mgmtDBDatabase:select(table, ...)
    return self.db:select(table, ...)
end

function Power_mgmtDBDatabase:update(table, ...)
    return self.db:update(table, ...)
end

function Power_mgmtDBDatabase:insert(table, ...)
    return self.db:insert(table, ...)
end

function Power_mgmtDBDatabase:delete(table, ...)
    return self.db:delete(table, ...)
end

function Power_mgmtDBDatabase:exec(...)
    return self.db:exec(...)
end

return Power_mgmtDBDatabase.new
